import runSaga from './runSaga';
import createChannel from './createChannel';

function createSagaMiddleware(){
  let boundRunSaga;
  const channel = createChannel(); /*{take(←相当于.once),publish}*/

  function sagaMiddleware(middlewareApi/*{getState,dispatch}*/){
    boundRunSaga = runSaga.bind(null, {...middlewareApi, channel})
    return function(next){ //下一个中间件的dispatch方法 本例中 就是store.dispatch
      //  ↓ 用了sagaMiddleware中间件后, redux的dispatch方法就变成了↓这个了
      return function(action){ //自己的dispatch方法
        /*const result =*/ next(action);
        channel.publish(action); //← todo 放在next之后 还是 之前？ 应该是放在之后, 因为要用saga处理的动作 我们一般是不会写在reducer里的, 而是用take监听该动作, 故可以让这些动作先到reducer里找一转, 找不到再走我们的saga里去看
        /*
          redux-saga 是一个 redux 的中间件，而中间件的作用是为 redux 提供额外的功能。
          在 reducers 中的所有操作都是同步的并且是纯粹的，即 reducer 都是纯函数，纯函数是指一个函数的返回结果只依赖于它的参数，并且在执行过程中不会对外部产生副作用，即给它传什么，就吐出什么。
          但是在实际的应用开发中，我们希望做一些异步的（如Ajax请求）且不纯粹的操作（如改变外部的状态），这些在函数式编程范式中被称为“副作用”。

          即纯的操作交给reducer
          不纯的,有副作用的,比如一些异步任务可以交给我们的saga
        */

        //return result;
      }
    }
  }

  sagaMiddleware.run = (saga) => boundRunSaga(saga);

  return sagaMiddleware;
}

export default createSagaMiddleware;
